package com.onlygx.dva.config.annotation.security;

import cn.hutool.core.collection.CollectionUtil;
import com.onlygx.dva.web.ui.service.BaseRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import com.onlygx.dva.common.entity.dto.CoreUserDTO;
import com.onlygx.dva.common.exception.AuthException;
import com.onlygx.dva.common.utils.RequestLogUtil;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 角色认证切面处理器
 * </p>
 *
 * @author 高祥
 * @since 2023-08-07
 */
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class RolesPointHandler {

    final HttpServletRequest httpServletRequest;

    final BaseRoleService baseRoleService;

    @Pointcut("@annotation(com.onlygx.dva.config.annotation.security.RequireRoles)")
    public void requireRoles(){}

    @Before("requireRoles()")
    public void beforeHandler(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        RequireRoles requireRoles = methodSignature.getMethod().getAnnotation(RequireRoles.class);
        //获取header 中 current-user 信息
        CoreUserDTO userDTO = RequestLogUtil.getRequestUser(httpServletRequest);
        //获取注解中指定的角色列表
        List<String> roles = Arrays.asList(requireRoles.value());
        //如果注解内容为空，不进行判断。
        if(CollectionUtil.isEmpty(roles)) return;
        //获取注解中多角色的判定方式，默认 or
        AuthNorm norm = requireRoles.authNorm();
        log.info("角色判断，当前用户：{}，访问 {} 方法需要角色：{}，多角色判断逻辑是：{}"
                ,userDTO,methodSignature.getName(),roles,norm);
        //执行判定
        boolean judgeResult = baseRoleService.judgeRoles(userDTO.getUid(),roles,norm);
        if(!judgeResult) throw new AuthException("当前用户无此角色。");

    }

}
